#include <iostream>
#include <unordered_map>
#include <vector>
#include <string>
using namespace std;
struct File
{
    string name;
    string content;
    int proCode;
    string address;
    int filesize;
    bool isOpen;
    // File():length(0),isOpen(false){}
    File(string name, string address)
        : name(name), address(address), filesize(0),proCode(2), isOpen(false) {}
};

class FileSystem
{
private:
    unordered_map<string, string> users;
    unordered_map<string, vector<File>> directories;
    string currentUser;
    int fileCount;

public:
    FileSystem() : fileCount(0)
    {
        // Initializing with a default user for simplicity
        users["admin"] = "123456";
        directories["admin"] = {};
        currentUser = "";
    }
    string getCurrentUser()
    {
        return currentUser;
    }
    void adduser(const string &username, const string &password)
    {
        if (users.find(username) == users.end())
        {
            users[username] = password;
            directories[username] = {};
        }
    }
    bool login(const string &username, const string &password)
    {
        if (users.find(username) != users.end() && users[username] == password)
        {
            setCurrentUser(username);
            cout << "Login successful!" << endl;
            return true;
        }
        cout << "Login failed!" << endl;
        return false;
    }
    bool setCurrentUser(string name)
    {
        currentUser = name;
        return true;
    }
    void dir()
    {
        if (currentUser.empty())
        {
            cout << "No user logged in!" << endl;
            return;
        }

        cout << "Directory for user: " << currentUser << endl;
        for (const auto &file : directories[currentUser])
        {
            cout << "Name: " << file.name
                 << ", Address: " << file.address
                 << ", Protection: " << file.proCode
                 << ", Length: " << file.filesize << endl;
        }
    }

    void create(const string &filename)
    {
        if (currentUser.empty())
        {
            cout << "No user logged in!" << endl;
            return;
        }
       const string  base = "home/";
        directories[currentUser].emplace_back(filename, base + currentUser + "/" + filename);
        chmod(filename, 2);
        cout << "File created: " << filename << endl;
    }

    void remove(const string &filename)
    {
        if (currentUser.empty())
        {
            cout << "No user logged in!" << endl;
            return;
        }

        auto &files = directories[currentUser];
        for (auto it = files.begin(); it != files.end(); ++it)
        {
            if (it->name == filename)
            {
                files.erase(it);
                cout << "File deleted: " << filename << endl;
                return;
            }
        }
        cout << "File not found: " << filename << endl;
    }
    void chmod(const string &filename, int code)
    {
        if (currentUser.empty())
        {
            cout << "No user logged in!" << endl;
            return;
        }
        for (auto &file : directories[currentUser])
        {
            if (file.name == filename)
            {
                file.proCode = code;
                break;
            }
        }
        cout << "File not found: " << filename << endl;
    }
    void open(const string &filename)
    {
        if (currentUser.empty())
        {
            cout << "No user logged in!" << endl;
            return;
        }

        for (auto &file : directories[currentUser])
        {
            if (file.name == filename)
            {
                if (!file.isOpen)
                {
                    file.isOpen = true;
                    cout << "File opened: " << filename << endl;
                }
                else
                {
                    cout << "File already open: " << filename << endl;
                }
                return;
            }
        }
        cout << "File not found: " << filename << endl;
    }

    void close(const string &filename)
    {
        if (currentUser.empty())
        {
            cout << "No user logged in!" << endl;
            return;
        }

        for (auto &file : directories[currentUser])
        {
            if (file.name == filename)
            {
                if (file.isOpen)
                {
                    file.isOpen = false;
                    cout << "File closed: " << filename << endl;
                }
                else
                {
                    cout << "File is not open: " << filename << endl;
                }
                return;
            }
        }
        cout << "File not found: " << filename << endl;
    }

    void read(const string &filename)
    {
        if (currentUser.empty())
        {
            cout << "No user logged in!" << endl;
            return;
        }

        for (const auto &file : directories[currentUser])
        {
            if (file.name == filename)
            {
                if (file.isOpen)
                {
                    cout << "Reading file: " << filename << endl;
                    cout << "Content: " << file.content << endl;
                }
                else
                {
                    cout << "File is not open: " << filename << endl;
                }
                return;
            }
        }
        cout << "File not found: " << filename << endl;
    }

    void write(const string &filename, const string &content)
    {
  
        if (currentUser.empty())
        {
            cout << "No user logged in!" << endl;
            return;
        }

        for (auto &file : directories[currentUser])
        {
            if (file.name == filename)
            {
                if (file.isOpen)
                {
                    file.content = content;
                
                    file.filesize = content.size();
                    cout << "Written to file: " << filename << endl;
                }
                else
                {
                    cout << "File is not open: " << filename << endl;
                }
                return;
            }
        }
        cout << "File not found: " << filename << endl;
    }
    bool logout()
    {
        return setCurrentUser("");
    }
};

void cmd(FileSystem fs)
{
    while (true)
    {
        cout << '\n'
             << fs.getCurrentUser() << ">> ";
        string command;
        cin >> command;
        if (command == "quit")
        {
            printf("bye.\n");
            break;
        }
        if (command == "login")
        {
            string user, pwd;
            cin >> user >> pwd;
            fs.login(user, pwd);
        }
        if (command == "logout")
        {
            if (fs.logout())
                cout << "log out successful" << '\n';
        }

        if (command == "adduser")
        {
            string user, pwd;
            cin >> user >> pwd;
            fs.adduser(user, pwd);
        }
        if (command == "create")
        {
            string filename;
            cin >> filename;
            fs.create(filename);
        }
        if (command == "ls")
        {
            fs.dir();
        }
        if (command == "vim" || command == "vi")
        {
            string filename;
            cin >> filename;
            fs.open(filename);
            printf("\ninput the content:\n");
            string content;
            cin.ignore();
            getline(cin, content);
            fs.write(filename, content);
            cout << "write successful!\n";
        }

        if (command == "open")
        {
            string filename;
            cin >> filename;
            fs.read(filename);
        }

        if (command == "close")
        {
            string filename;
            cin >> filename;
            fs.close(filename);
        }

        if (command == "rm")
        {
            string filename;
            cin >> filename;
            fs.remove(filename);
        }
    }
}
int main()
{
    FileSystem fs;
    cmd(fs);
    return 0;
}
